package cn.atzxc.qy.service.impl;

import cn.atzxc.qy.domain.Address;
import cn.atzxc.qy.domain.User;
import cn.atzxc.qy.mapper.AddressMapper;
import cn.atzxc.qy.service.AddressService;
import cn.atzxc.qy.utils.JwtUtil;
import cn.atzxc.qy.utils.RedisCache;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
@Service
public class AddressServiceImpl implements AddressService {

    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private RedisCache redisCache;

    /**
     * 根据传递的ID，查询出指定用户的全部地址信息
     * 要判断用户地址中的删除按钮是否为1.如果为1，则表示已经删除
     *
     * 用户发送过来的请求
     *      首先查看redis中是否存在此信息，存在则直接返回，不存在则进行请求
     *      然后将查询出来的数据，放入到Redis中
     * @param token
     * @return
     */
    @Override
    public List<Address> getAddressList(String token) throws Exception {

        //通过token解析出指定的用户名ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        System.out.println(subject);

        // 根据传递的ID，查询出指定用户的全部地址信息
        List<Address> addresses;
        addresses = redisCache.getCacheObject("addresslist:" + subject);
        System.out.println(addresses);
        if (addresses == null) {
            System.out.println("缓存中无地址信息");
            LambdaQueryWrapper<Address> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Address::getUserId, subject);
            //等于0为用户没有删除
            queryWrapper.eq(Address::getIsDelete, 0);

            addresses = addressMapper.selectList(queryWrapper);
            for (Address address: addresses) {
                System.out.println(address);
            }

            //TODO 进行list排序，主要是把默认地址放在前面，然后根据时间排序
            Comparator<Address> addressComparator = Comparator.comparing(Address::getIsDefault).reversed();
//            Comparator<Address> addressComparator = Comparator.comparing(Address::getIsDefault).thenComparing(Address::getUpdateTime);
            addresses.sort(addressComparator);

            //把地址数据添加到缓存中
            redisCache.setCacheObject("addresslist:"+subject, addresses);
        }else {
            System.out.println("缓存中存在信息");
        }
        return addresses;
    }

    /**
     * 通过传递的地址ID 删除用户的指定地址
     * 首先把数据库中的地址is_delete信息 设置为1 表示删除
     * 然后使用 "addresslist:" + subject 把redis中的数据清空
     * 然后重新调用 getAddressList 方法，把用户地址信息查询出来并存入数据库
     * @param addressid
     * @return
     */
    @Override
    public int deleteAddressByAddressId(String addressid) {

        //查询
        LambdaQueryWrapper<Address> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Address::getAddressId, addressid);

        //查询出指定地址ID的全部信息
        Address address = addressMapper.selectOne(queryWrapper);

        //更新
        LambdaUpdateWrapper<Address> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Address::getAddressId, addressid); // 设置条件

        address.setIsDelete(1);
        //TODO 添加一个修改时间的字段
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date nowTime = new Date(); // 获取当前日期和时间
        String formattedDate = dateFormat.format(nowTime);
        address.setUpdateTime(formattedDate);


        int updated = addressMapper.update(address, updateWrapper);
        if (updated > 0) {
            System.out.println("更新成功");
            return updated;
        } else {
            System.out.println("更新失败");
            return updated;
        }
    }

    /**
     * 从前端接收到token 和 前端封装好的地址对象
     * 把获取到的token解析出用户的userid，设置到传递进来的地址对象中的userid中
     * 把完整的地址对象存入到地址表中
     * 清空redis中的地址对象，并重新查询地址数据，存入到redis中
     * @param token
     * @param address
     * @return
     * @throws Exception
     */
    @Override
    public int addAddress(String token, Address address) throws Exception {
        int insert=0;
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        try {
            //获取到用户的ID，用于做地址表的 用户外键
            long userId = Long.parseLong(subject);
            address.setUserId(userId);
            address.setIsDelete(0);
            String province = address.getProvince();
            //把获取到的值（天津市-市辖区-和平区），省，市，区分割出来
            String[] provinces = province.split("-");
            province = provinces[0];
            String city = provinces[1];
            String area = provinces[2];

            address.setProvince(province);
            address.setCity(city);
            address.setDistrict(area);
            //TODO 添加地址时间的字段
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date nowTime = new Date(); // 获取当前日期和时间
            String formattedDate = dateFormat.format(nowTime);
            address.setCreateTime(formattedDate);


            System.out.println("地址对象为："+address);

            //把获取到的地址对象，写入数据库
            insert = addressMapper.insert(address);
        } catch (NumberFormatException e) {
            // 处理转换失败的情况
            System.out.println("无法将字符串转换为 long 类型：" + subject);
            throw new RuntimeException("token解析错误");
        }

        return insert;
    }

    /**
     * 通过地址ID，修改指定地址的地址信息
     * 通过token解析出用户的userId，从地址对象中获取到地址ID
     * 通过地址ID，作为条件，去更新其他地址的信息
     * 更新后，清空redis，并调用查询方法，重新查询，并返回出来的新地址
     * @param token
     * @param address
     * @return
     */
    @Override
    public int updateAddressById(String token, Address address) throws Exception {
        //从token中获取到用户ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        //获取到传递进来的地址ID
        long addressId = address.getAddressId();
        System.out.println("用户ID为:"+subject+"，地址ID为："+addressId);
        //省份处理
        String province = address.getProvince();
        //把获取到的值（天津市-市辖区-和平区），省，市，区分割出来
        String[] provinces = province.split("-");
        province = provinces[0];
        String city = provinces[1];
        String area = provinces[2];

        address.setProvince(province);
        address.setCity(city);
        address.setDistrict(area);
        //TODO 添加一个修改时间的字段
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date nowTime = new Date(); // 获取当前日期和时间
        String formattedDate = dateFormat.format(nowTime);
        System.out.println("更新时间为："+formattedDate);
        address.setUpdateTime(formattedDate);


        System.out.println("地址对象为："+address);

        //根据地址ID进行修改地址喜信息
        //TODO 对传递进来的参数进行判断

        LambdaUpdateWrapper<Address> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Address::getAddressId, addressId); // 根据地址ID，设置修改条件
        int updateNum = addressMapper.update(address, updateWrapper);
        return updateNum;
    }


    /**
     * 设置默认地址
     * 1.根据token解析出当前的用户ID
     * 2.通过 用户ID 查询出当前用户 字段is_defualt字段为1的地址，并获取到地址ID
     * 3.通过传递进来的地址ID，是否与查询出来的地址ID 一致
     *      如果一致，则不做操作，返回0
     *      如果不一致，则把查询到的地址，中的is_default字段设置为0（已经不是默认地址）
     *      通过传递进来的地址ID以及用户ID查询出指定的地址信息，并把查询出来的 is_defualt中的字段设置1（表示设置为默认地址）
     * @param token
     * @param addressOld
     * @param date
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int setDefaultAddress(String token, Address addressOld, Date date) throws Exception {
        //1.根据token解析出当前的用户ID
        Claims claims = JwtUtil.parseJWT(token);
        String subject = claims.getSubject();
        //2.通过 用户ID 查询出当前用户 字段is_defualt字段为1的地址，并获取到地址ID
        LambdaQueryWrapper<Address> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Address::getUserId, subject);//设置查询指定用户下的地址
        queryWrapper.eq(Address::getIsDefault,1);
        Address addressNew = addressMapper.selectOne(queryWrapper);
        //3.通过传递进来的地址ID，是否与查询出来的地址ID 一致
        if(addressOld.getAddressId() == addressNew.getAddressId()){
            //如果一致，则不做操作，返回0
            System.out.println("点击的位置就是默认地址的位置");
            return 0;
        }else {
            // 不一致，则把查询到的地址，中的is_default字段设置为0（已经不是默认地址）
            //把原有的默认地址设置为0，表示取消默认地址
            addressMapper.updateIsDefaultByAddress(addressNew.getAddressId(), 0);
            //把传递进来的默认地址设置为1，表示设置默认地址
            addressMapper.updateIsDefaultByAddress(addressOld.getAddressId(), 1);
            return 1;
        }
    }

    @Override
    public List<Address> selectAddressList() {
        List<Address> addresses = addressMapper.selectAddressList();
        return addresses;
    }

}
